//
//@File    :	15.17_riit1.cpp
//@Time    :	2022/03/20 20:49:29
//@Auther  :	Sun Sheng
//@Contact :	970340843@qq.com
//@Desc    :	using the RIIT dynamic_cast operator
//

//RIIT 运行阶段类型识别
//只能用于包含虚函数的类层次结构
//应当尽可能使用虚函数,只在必要时使用RIIT

//dynamic_cast运算符将使用一个指向基类的指针来生成一个指向派生类的指针,否则,该运算符返回0-即空指针
//使用: dynamic_cast<Type *>(pt) 
//指向的对象(*pt)
//typeid运算符返回一个指出对象的类型的值
//type_info结构存储了有关特定类型的信息
#include <iostream>
#include <cstdlib>
#include <ctime>

using std::cout;
class Grand
{
private:
    int hold;
public:
    Grand(int h=0) :hold(h){}
    virtual void Speak() const {cout<<"I am a grand class!\n";}
    virtual int Value() const{return hold;}
};

class Superb:public Grand
{    
public:
    Superb(int h=0):Grand(h) {}
    void Speak() const {cout<<" I am a superb class!\n";}
    virtual void Say() const {cout<<"I hold the wuperb value of "<<Value()<<"!\n";}
};

class Magnificent:public Superb
{   
private:
    char ch;
public:
    Magnificent(int h=0,char c='A'):Superb(h),ch(c) {}
    void Speak() const {cout<<" I am a Magnificent class!!!\n";}
    void Say() const {cout<<"I hold the character "<<ch<<" and the integer"<<Value()<<"!\n";
};

// Grand *GetOne();
Grand * GetOne()
{
    Grand * p;
    switch (std::rand()%3)
    {
    case 0:
        p=new Grand(std::rand()%100);
        break;
    case 1:
        p=new Superb(std::rand()%100);
        break;
    case 2:
        p=new Magnificent(std::rand()%100,'A'+std::rand()%26);
        break;
    }
    return p;
}

int main()
{
    std::srand(std::time(0));
    Grand *pg;
    Superb *ps;
    for (int i = 0; i < 5; i++)
    {
        pg=GetOne();
        pg->Speak();
        if (ps=dynamic_cast<Superb *>(pg))
        {
            ps->Say();
        } 
    }
    return 0;
}
